package win.larryzeal.nio2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * Created by 张少昆 on 2017/9/26.
 */
public class NioServer {
    private ServerSocketChannel server;
    int port = 8080;
    private Selector selector;

    ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
    ByteBuffer recvBuffer = ByteBuffer.allocate(1024);

    int client_id = 10000;

    Map<SelectionKey, String> sessionMsg = new HashMap<>();
    Map<SelectionKey, String> clientIdMsg = new HashMap<>();

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public NioServer(int port) throws IOException{
        this.port = port;
        server = ServerSocketChannel.open(); //enclose socket
        server.socket().bind(new InetSocketAddress(this.port)); // server socket listen port
        server.configureBlocking(false);
        selector = Selector.open();
        server.register(selector, SelectionKey.OP_ACCEPT);// ready to accept client's connection
        System.out.println("system initialized! listen on port: " + this.port);
    }

    private void listener() throws IOException{
        while(true){
            int eventCount = selector.select();
            if(eventCount == 0){
                continue;
            }
            // get current event set
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while(iterator.hasNext()){
                process(iterator.next());
                iterator.remove(); //when processed, remove current event
            }
        }
    }

    private void process(SelectionKey key){
        SocketChannel client = null;
        try{
            if(key.isValid() && key.isAcceptable()){
                client = server.accept();
                ++client_id;
                client.configureBlocking(false);
                client.register(selector, SelectionKey.OP_READ);
            } else if(key.isValid() && key.isReadable()){ // in case remote host shutdown accidently
                recvBuffer.clear();
                client = (SocketChannel) key.channel();
                int len = client.read(recvBuffer);
                if(len > 0){
                    String msg = new String(recvBuffer.array(), 0, len);
                    sessionMsg.put(key, msg);
                    System.out.println(Thread.currentThread().getId() + msg);
                    clientIdMsg.put(key, client_id+"");
                    client.register(selector, SelectionKey.OP_WRITE);
                }

            }
        } catch(IOException e){
            e.printStackTrace();

        }
    }

    public static void main(String[] args){
        // now we need a thread to monitor

    }


}
